<template>
  <a-card>
    <a-row class="mb-10">
      <a-col>
        <a-button type="primary" class="mr-10" @click="showModal()"
          >新增</a-button
        >
      </a-col>
    </a-row>
    <a-table
      :columns="columns"
      :row-key="(record) => record.path"
      :data-source="state.dataSource"
      :loading="state.loading"
      @change="handleTableChange"
    >
      <template #action="{ record }">
        <span>
          <a-button type="link" @click="() => showModal(record)">
            修改
          </a-button>
          <a-popconfirm title="确定删除?" @confirm="() => handleDelete(record)">
            <a-button
              :disabled="['admin'].includes(record.roleKey)"
              type="link"
            >
              删除
            </a-button>
          </a-popconfirm>
        </span>
      </template>
    </a-table>

    <a-modal
      v-model:visible="modalState.visible"
      :title="modalState.title"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <a-form
        ref="formRef"
        :model="formState"
        :rules="rules"
        :labelCol="{ style: { width: '100px' } }"
      >
        <a-form-item label="上级菜单" name="parentPath">
          <a-tree-select
            allowClear
            v-model:value="formState.parentPath"
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            :tree-data="modalState.treeData"
            :replaceFields="{
              key: 'key',
              value: 'key',
            }"
            placeholder="Please select"
          >
          </a-tree-select>
        </a-form-item>
        <a-form-item label="菜单类型" name="menuType">
          <a-radio-group v-model:value="formState.menuType">
            <a-radio :value="1">目录</a-radio>
            <a-radio :value="2">菜单</a-radio>
            <!-- <a-radio :value="3">按钮</a-radio> -->
          </a-radio-group>
        </a-form-item>
        <a-form-item label="菜单名称" name="title">
          <a-input v-model:value="formState.title" allowClear />
        </a-form-item>
        <a-form-item label="菜单排序" name="orderNo">
          <a-input-number v-model:value="formState.orderNo" :min="1" />
        </a-form-item>
        <a-form-item label="路由地址" name="path">
          <a-input v-model:value="formState.path" allowClear />
          <a-tag color="warning">可以选择组件路径自动填充</a-tag>
        </a-form-item>
        <a-form-item
          label="组件路径"
          name="component"
          v-if="formState.menuType !== 1"
        >
          <a-select
            v-model:value="formState.component"
            show-search
            placeholder="请选择组件路径"
            :options="componentOptions"
            @change="changeComponentPath"
          ></a-select>
        </a-form-item>
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="是否隐藏" name="hideMenu">
              <a-switch v-model:checked="formState.hideMenu" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="是否缓存" name="keepAlive">
              <a-switch v-model:checked="formState.keepAlive" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="是否外链" name="isLink">
              <a-switch v-model:checked="formState.isLink" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="是否iframe" name="isIframe">
              <a-switch v-model:checked="formState.isIframe" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-form-item label="外链地址" name="linkUrl" v-if="formState.isLink">
          <a-input v-model:value="formState.linkUrl" />
        </a-form-item>
        <a-form-item
          label="iframe地址"
          name="iframeUrl"
          v-if="formState.isIframe"
        >
          <a-input v-model:value="formState.iframeUrl" />
        </a-form-item>
      </a-form>
    </a-modal>
  </a-card>
</template>

<script setup>
import { reactive, ref } from "@vue/reactivity";
import { getAllRoutes, addRoute, updateRoute, deleteRoute } from "@/api/routes";
import { onBeforeMount } from "@vue/runtime-core";
import { readViews } from "@/utils/autoRead";

function initTree(treeNode) {
  for (let i = 0; i < treeNode.length; i += 1) {
    let item = treeNode[i];
    const { path, meta = {} } = item;
    treeNode[i] = {
      ...item,
      ...meta,
      key: path,
    };
    if (item.children && item.children.length > 0) {
      initTree(item.children);
    }
  }
  return treeNode;
}

const columns = [
  {
    title: "菜单名称",
    dataIndex: "title",
  },
  {
    title: "排序",
    dataIndex: "orderNo",
  },
  {
    title: "组件路径",
    dataIndex: "component",
  },
  {
    title: "操作",
    dataIndex: "action",
    slots: { customRender: "action" },
  },
];

const state = reactive({
  dataSource: [],
  searchInfo: {},
  loading: false,
});

const init = () => {
  state.loading = true;
  // 获取菜单列表
  getAllRoutes()
    .then((res) => {
      state.dataSource = initTree(res.data);
    })
    .finally(() => {
      state.loading = false;
    });
};

const handleSearch = () => {
  init();
};

const handleTableChange = (pag, filters) => {
  state.searchInfo = {
    ...state.searchInfo,
    ...filters,
  };
  handleSearch();
};

const handleDelete = (record) => {
  deleteRoute(record.id).then(() => {
    init();
  });
};

onBeforeMount(() => {
  init();
});

// 弹窗
const componentOptions = Object.keys(readViews()).map((item) => {
  const value = item.replace(".vue", "");
  return {
    value,
    label: value,
  };
});
const modalState = reactive({
  visible: false,
  title: "",
  treeData: [],
  // 组件路径集合
  componentOptions,
});
// 添加编辑表单
const formRef = ref();
const getInitialData = () => ({
  path: "",
  component: "",
  title: "",
  parentPath: "",
  orderNo: "",
  hideMenu: false,
  keepAlive: false,
  isLink: false,
  linkUrl: "",
  isIframe: false,
  iframeUrl: "",
  // 菜单类型:1目录、2菜单
  menuType: 2,
});
const formState = reactive(getInitialData());
const rules = {
  path: [{ required: true, message: "请输入", trigger: "blur" }],
  component: [{ required: true, message: "请输入", trigger: "blur" }],
  title: [{ required: true, message: "请输入", trigger: "blur" }],
  orderNo: [
    { type: "number", required: true, message: "请输入", trigger: "blur" },
  ],
  linkUrl: [{ required: true, message: "请输入", trigger: "blur" }],
  iframeUrl: [{ required: true, message: "请输入", trigger: "blur" }],
};

// 打开弹窗
const showModal = (record) => {
  if (!record) {
    modalState.title = "新增";
  } else {
    Object.assign(formState, { ...record });
    modalState.title = "修改";
  }
  // 获取系统菜单
  getAllRoutes().then((res) => {
    modalState.treeData = initTree(res.data);
  });
  modalState.visible = true;
};

// 组件路径改变
const changeComponentPath = (val) => {
  formState.path = `/${val.slice(0, -"/index".length)}`;
};

const handleOk = () => {
  formRef.value
    .validate()
    .then(() => {
      let {
        id,
        path,
        component,
        title,
        parentPath,
        orderNo,
        hideMenu,
        keepAlive,
        isLink,
        linkUrl,
        isIframe,
        iframeUrl,
        menuType,
      } = formState;
      const name = path.slice(1).replaceAll("/", "-");
      if (menuType === 1) {
        component = "LayoutParentView";
      }
      const params = {
        id,
        path,
        name,
        component,
        meta: {
          title,
          parentPath,
          orderNo,
          hideMenu,
          keepAlive,
          isLink,
          linkUrl,
          isIframe,
          iframeUrl,
          menuType,
        },
      };
      if (modalState.title === "新增") {
        addRoute(params).then((res) => {
          console.log("res: ", res);
          handleCancel();
          init();
        });
      } else {
        updateRoute(params).then((res) => {
          console.log("res: ", res);
          handleCancel();
          init();
        });
      }
    })
    .catch((error) => {
      console.log("error", error);
    });
};
const handleCancel = () => {
  modalState.visible = false;
  formRef.value.resetFields();
  Object.assign(formState, getInitialData());
};
</script>

<style lang="scss" scoped></style>
